import axios from 'axios'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/auth'
import { merge } from 'lodash-es'
import qs from 'qs'
const env = import.meta.env

// 创建axios实例
// 基础数据
export const service = axios.create({
	baseURL: env.VITE_APP_BASE_API, // api的base_url
	timeout: 1000 * 60 * 10, // 请求超时时间
	withCredentials: true,
	headers: {
		'Content-Type': 'application/json; charset=utf-8',
		'Cache-Control': 'no-cache'
	}
})
// Axios连接池操作
// window.axiosPromiseArr = [] // axios中设置放置要取消的对象
// 声明一个数组用于存储每个ajax请求的取消函数和ajax标识
const pending = []
const CancelToken = axios.CancelToken
// 连接池白名单
const pengdingWhite = [
	// '/api/asset2/gfmasseledepment/v1/getListByRgid&post',
]
const removePending = config => {
	let allUrl = [
		config.url,
		config.method,
		qs.stringify(config.params),
		qs.stringify(config.data)
	].join('&')
	for (const p in pending) {
		if (pending[p].u === allUrl) {
			// 当前请求在数组中存在时执行函数体
			pending[p].f() // 执行取消操作
			pending.splice(p, 1) // 把这条记录从数组中移除
		}
	}
}
/**
 * 请求拦截
 */
service.interceptors.request.use(
	config => {
		// 从store中获取token并添加到请求头供后端作权限校验
		if (getToken()) {
			config.headers['Authorization'] = 'bearer' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
		}
		// 在一个ajax发送前执行一下取消操作
		removePending(config)
		config.cancelToken = new CancelToken(c => {
			let allUrl = [
				config.url,
				config.method,
				qs.stringify(config.params),
				qs.stringify(config.data)
			].join('&')
			// 处理白名单
			if (!pengdingWhite.includes([config.url, config.method].join('&'))) {
				// 将请求地址和方法添加到pending数组中
				pending.push({ u: allUrl, f: c })
			}
			// 路由跳转时取消之前的请求 暂时不用 -> 因为好多keep-alive组件，取消后切换导航时就不会再触发请求了
			// window.axiosPromiseArr.push({ u: config.url + '&' + config.method, c: c })
		})
		return config
	},
	error => {
		console.error(error) // for debug
		return Promise.reject(error)
	}
)

/**
 * 响应拦截
 */
service.interceptors.response.use(
	response => {
		return response
	},
	error => {
		// 处理取消请求
		if (axios.isCancel(error)) {
			throw new axios.Cancel('cancel request')
		}
		if (error.toString().includes('401')) {
			// MessageBox.confirm(
			//   '你已被登出，可以取消继续留在该页面，或者重新登录',
			//   '确定登出',
			//   {
			//     confirmButtonText: '重新登录',
			//     cancelButtonText: '取消',
			//     type: 'warning'
			//   }
			// ).then(() => {
			//   removeToken().then(() => {
			//     // window.open(`${window.location.origin}#${localStorage.getItem('SYSFICALAREA') ? '/' + localStorage.getItem('SYSFICALAREA') : ''}/login`, '_top')
			//     location.reload() // 为了重新实例化vue-router对象 避免bug
			//   })
			// })
		} else if (error.toString().includes('404')) {
			ElMessage.error('该服务未启动或服务不存在')
		} else if (error.response.data && error.response.data.msg) {
			ElMessage.error(error.response.data.msg)
		} else if (error.toString().includes('500')) {
			ElMessage.error('服务器错误，请联系管理员')
		} else {
			ElMessage.error('服务器错误，请联系管理员')
		}
		return Promise.reject(error)
	}
)
// /**
//  * 请求地址处理
//  * @param {*} actionName action方法名称
//  */
// service.adornUrl = (actionName) => {
//   //  api的base_url
//   return env.VITE_APP_BASE_API + actionName
// }

/**
 * get请求参数处理
 * @param {*} params 参数对象
 * @param {*} openDefultParams 是否开启默认参数?
 */
service.adornParams = (params = {}, openDefultParams = true) => {
	var defaults = {
		// t: new Date().getTime(),
	}

	return openDefultParams ? merge(defaults, params) : params
}

/**
 * post请求数据处理
 * @param {*} data 数据对象
 * @param {*} openDefultdata 是否开启默认数据?
 * @param {*} contentType 数据格式
 *  json: 'application/json; charset=utf-8'
 *  form: 'application/x-www-form-urlencoded; charset=utf-8'
 */
service.adornData = (
	data = {},
	openDefultdata = true,
	contentType = 'json'
) => {
	var defaults = {
		// t: new Date().getTime(),
	}
	data = openDefultdata ? merge(defaults, data) : data
	return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}

export function adornData(
	data = {},
	openDefultdata = true,
	contentType = 'json'
) {
	var defaults = {
		// t: new Date().getTime(),
	}
	data = openDefultdata ? merge(defaults, data) : data
	return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}
export function adornParams(params = {}, openDefultParams = true) {
	var defaults = {
		// t: new Date().getTime(),
	}
	return openDefultParams ? merge(defaults, params) : params
}

const request = function(requestInfo) {
	return new Promise((resolve, reject) => {
		service(requestInfo)
			.then(
				response => {
					// console.log('返回--', response)
					resolve(response)
				},
				err => {
					if (err.Cancel) {
						// console.log(err)
					} else {
						reject(err)
					}
				}
			)
			.catch(err => {
				reject(err)
			})
	})
}
// export default service
export default request